package net.scala.chapter2.test

import java.io.File

import org.junit.Assert._
import org.junit.{Before, Test}
import org.scalatest.junit.AssertionsForJUnit

/**
 * @author Barudisshu
 */
class TestScala extends AssertionsForJUnit {

  var name: StringBuilder = _
  val evenNumbers = List(2, 4, 6, 8, 10)

  /*------------
   |注意命名规法
   ------------*/

  @Before def initialize() {
    name = new StringBuilder("Barudisshu")
  }

  @Test def upperCase() {
    assertEquals("是否包含大写字母？", true, name.exists(_.isUpper))
  }

  /**
   * 匿名函数测试
   */
  @Test def anonymous() {

    val ano1 = evenNumbers.foldLeft(0) { (a: Int, b: Int) => a + b}
    val ano2 = evenNumbers.foldLeft(0) { (a, b) => a + b}
    val ano3 = evenNumbers.foldLeft(0) {
      _ + _
    }

    if (ano1 == ano2 && ano1 == ano3)
      println(f"匿名函数输出结果为 $ano1")

  }

  /*------------
   |闭包测试开始
   ------------*/
  /**
   * 闭包
   * 闭包中传入的参数为方法，因此闭包中的参数写法为：
   * def breakable(op: => Unit) { ... }
   * 其中op为函数参数名，=> 表示传入的是一个方法， => 后面为传入方法的返回类型
   */
  @Test def closure() {

    breakable(install()) // breakable是一个闭包
    breakable {
      // 因为install不包含参数，所以可以声明为行内形式
      val env = System.getenv("JAVA_HOME")
      if (env == null) break
      println(f"found java home at: $env \nlets do the real work!")
    }
  }

  val breakException = new RuntimeException("break Exception")

  def breakable(op: => Unit) {
    // 定义一个闭包，传入一个参数为返回Unit的空参数函数
    try {
      op
    } catch {
      case _: Throwable =>
    }
  }

  def break = throw breakException

  def install() = {
    val env = System.getenv("SCALA_HOME")
    if (env == null) break
    println(f"found scala home at $env\n, lets do the real work!")
  }

  /*------------
   |闭包测试结束
   ------------*/

  /*------------
 |for-comprehension start
 ------------*/
  /**
   * For-comprehension
   * 测试两种for循环代码副作用
   */
  @Test def forComprehension() {
    fo1()
    fo2()
  }

  val files = new File(getClass.getClassLoader.getResource("").getPath).listFiles()

  def fo1() {
    for (file <- files) {
      val fileName = file.getName
      if (fileName.endsWith(".txt")) println(file)
    }
  }

  def fo2() {
    for (

      file <- files;
      fileName = file.getName
      if fileName.endsWith(".txt")
    )
      println(file)
  }

  /*------------
   |for-comprehension end
   ------------*/
}
